package com.hfi.mymap;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.*;

/**
 * @author ChangLiang
 * @date 2019/5/20
 */
public class MyParamNameResolver {

    public static final String GENERIC_NAME_PREFIX = "param";

    private final SortedMap<Integer,String> names;

    private boolean hasParamAnnotation;

    public MyParamNameResolver(Method method) {
        Annotation[][] paramAnnotations = method.getParameterAnnotations();
        SortedMap<Integer, String> map = new TreeMap<>();
        int paramCount = paramAnnotations.length;
        for (int paramIndex = 0; paramIndex < paramCount; paramIndex++) {
            String name = null;
            for (Annotation annotation : paramAnnotations[paramIndex]) {
                if (annotation instanceof MyParam) {
                    hasParamAnnotation = true;
                    name = ((MyParam)annotation).value();
                    break;
                }
            }
            if (name == null) {
                name = String.valueOf(map.size());
            }
            map.put(paramIndex, name);
        }
        names = Collections.unmodifiableSortedMap(map);
    }

    public Object getNameParams(Object[] args) {
        final int paramCount = names.size();
        // 参数为null或没有参数直接返回
        if (args == null || paramCount == 0) {
            return null;
        } else {
            final Map<String, Object> param = new HashMap<>();
            int i = 0;
            // 遍历names集合；{0=id, 1=lastName}
            for (Map.Entry<Integer, String> entry : names.entrySet()) {
                // names集合的value作为key;  names集合的key又作为取值的参考
                param.put(entry.getValue(), args[entry.getKey()]);
                // add generic param names (param1, param2)
                final String genericParamName = GENERIC_NAME_PREFIX + (i + 1);
                // 额外的将每一个参数也保存到map中，使用新的key：param1...paramN
                if (!names.containsValue(genericParamName)) {
                    param.put(genericParamName, args[entry.getKey()]);
                }
                i++;
            }
            return param;
        }
    }
}
